package cn.taobaoke.restful.filter;

import cn.taobaoke.restful.domain.DomainEntity;
import cn.taobaoke.restful.domain.DomainRepository;
import lombok.RequiredArgsConstructor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Optional;

/**
 * 根据注册的二级域名过滤用户访问.
 *
 * @author yangzuo
 * @since 2017-05-04 20:26
 */
@WebFilter
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DomainFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        logger.info("Original Request: {} {} {}", request.getMethod(), request.getRequestURL(), request.getRemoteHost());

        String serverName = request.getServerName();
        String uri = request.getRequestURI();
        String domainEnd = "." + topLevelDomain;
        String wwwDomain = "www" + domainEnd;
        String apiDomain = "api" + domainEnd;

        // www域名和顶级域名保留使用，根据情况做修改
        if (uri.startsWith(STATIC_DATA_RESOURCE) || uri.startsWith(STATIC_FILE) || wwwDomain.equals(serverName) || uri.startsWith(STATIC_INVITE_CODE) || topLevelDomain.equals(serverName)) {
            doFilter(request, response, filterChain);
            return;
        }

        // 处理用户自己注册的域名
        Optional<DomainEntity> domainEntity = domainRepository.findByUserDomain(serverName);
        if (domainEntity.isPresent()) {
            String changedUri = "/" + domainEntity.get().getDomain() + uri;
            request.getRequestDispatcher(changedUri).forward(request, response);
            return;
        }

        if (serverName.endsWith(domainEnd)) {

            String secondDomain = request.getHeader("X-Customer-Domain");
            if (secondDomain == null) {
                if (apiDomain.equals(serverName)) {
                    request.getRequestDispatcher("/test/1"  + uri).forward(request, response);
                    return;
                } else {
                    secondDomain = serverName.substring(0, serverName.lastIndexOf(domainEnd));
                }
            }

            Optional<DomainEntity> entity = domainRepository.findByDomain(secondDomain);
            String realUri;
            if (entity.isPresent()) {
                realUri = "/" + secondDomain + "/" + entity.get().getId() + uri;
            } else {
                realUri = "/api/error?msg=不存在的二级域名[" + secondDomain + "]";
            }

            request.getRequestDispatcher(realUri).forward(request, response);
            return;
        }

        doFilter(request, response, filterChain);
    }

    @Value("${tbk.top.level.domain}")
    private String topLevelDomain;

    private final DomainRepository domainRepository;

    private static final String STATIC_FILE = "/api/files/images";

    private static final String STATIC_DATA_RESOURCE = "/api/datasources";

    private static final String STATIC_INVITE_CODE = "/api/invitecodes";

    private Logger logger = LogManager.getLogger(DomainFilter.class);
}
